package demo02;

import demo02.gun.CalcBaseVisitor;
import demo02.gun.CalcLexer;
import demo02.gun.CalcParser;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2016/6/22.
 */
public class EvalVisitor extends CalcBaseVisitor<Integer> {
    // "memory" for our calculator; variable/value pairs go here
    Map<String, Integer> memory = new HashMap<>() ;

    // stat : ID '=' expr
    @Override
    public Integer visitAssign(CalcParser.AssignContext ctx) {
        String id = ctx.ID().getText() ;        // id is left-hand side of '='
        int value = visit(ctx.expr()) ;         // compute value of expression on right
        memory.put(id, value) ;
        return value ;
    }

    // stat : expr
    @Override
    public Integer visitPrintExpr(CalcParser.PrintExprContext ctx) {
        Integer value = visit(ctx.expr()) ;     // evaluate the expr child
        System.out.println(value);              // print the result
        return 0 ;                              // return dummy value
    }

    // expr : INT
    @Override
    public Integer visitInt(CalcParser.IntContext ctx) {
        return Integer.valueOf(ctx.INT().getText()) ;
    }

    // expr : ID
    @Override
    public Integer visitId(CalcParser.IdContext ctx) {
        String id = ctx.ID().getText();
        if (memory.containsKey(id)) {
            return memory.get(id);
        }
        return 0;
    }

    // expr : expr op=(MUL|DIV) expr   # mulDiv
    @Override
    public Integer visitMulDiv(CalcParser.MulDivContext ctx) {
        int left = visit(ctx.expr(0)) ;
        int right = visit(ctx.expr(1)) ;
        if (ctx.op.getType() == CalcLexer.MUL) {
            return left * right ;
        }
        return left / right ;
    }

    // expr : expr op=(ADD|SUB) expr
    @Override
    public Integer visitAddSub(CalcParser.AddSubContext ctx) {
        int left = visit(ctx.expr(0)) ;
        int right = visit(ctx.expr(1)) ;
        if (ctx.op.getType() == CalcParser.ADD) {
            return left + right ;
        }
        return left - right ;
    }

    // expr : '(' expr ')'
    @Override
    public Integer visitParens(CalcParser.ParensContext ctx) {
        return visit(ctx.expr()); // return child expr's value
    }
}
